﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using Util;
using Dominio.Negocio;
using Dominio.Entidades;

public enum ActivarEdicion
{
    Festivos,
    JornadaVerano,
    Ausencias,
    Vacaciones,
    Compensasion
}

public partial class Control_ListCalender : System.Web.UI.UserControl
{
    //Todo: Poner las descripción de la propidades para que se vean en la propiedades del control
    #region Variables.

    private bool cambioAnyo=false;
    private bool forzaUpdatePanel = false;
    /// <summary>
    /// Almacena la propiedades que se deben mantener a través de los postback
    /// </summary>
    [Serializable]
    private struct Propiedades {
        public int idFestivo;
        public int? idEdificio;
        public int anyo;
        public bool _festivo;
        public bool _jornadaVerano;
        public bool _ausencias;
        public bool _vacaciones;
        public bool _compensasion;
        public bool _asuntosPropios;
        public bool _dayIsSelectable;
        public ActivarEdicion _tipoEdicion;
    };
    
    private Propiedades miProperty = new Propiedades();

    //Todo:quitar es una variable de control para controlar las veces que entra en el evento de pintado de los días.
    private int cont = 0;

    private Festivos_DLL festivos = new Festivos_DLL();
    private JornadaVerano_BLL jorVerano = new JornadaVerano_BLL();
    private Vacaciones_BLL oVacaciones = new Vacaciones_BLL();
    private List<Festivo> listFestivos;
    private List<JornadaVerano> listJorVerano;
    private List<DetalleSeguimiento> listVacaciones;


    Image imgOk;
    Image imgNotOk;
    Image imgQuestion;

    #endregion

    #region Propiedades. 
  
    private ActivarEdicion TipoEdicion
    {
        get { return miProperty._tipoEdicion; }
        set { miProperty._tipoEdicion = value; SaveControlState(); }
    }

    private int? IdEdificio { 
        get {

            return miProperty.idEdificio;
        }
        set {
            miProperty.idEdificio = value;
            SaveControlState();
        } 
    }

    private int IdFestivo
    {
        get
        {
            return miProperty.idFestivo;
        }
        set
        {
            miProperty.idFestivo = value;
            SaveControlState();
        }
    }

    public int Anyo
    {
        get { return miProperty.anyo; }
        set { miProperty.anyo = value; SaveControlState(); }
    }

    [Browsable(true)]
    [Themeable(false)]
    [Category("Behavior")]
    [Description("Establece si el control va a pintar los días festivos")]
    [DefaultValue(false)]
    public bool Festivo
    {
        get 
        { 
            return miProperty._festivo;
        }
        set 
        { 
            miProperty._festivo = value;
            SaveControlState();
        }
    }

    [Browsable(true)]
    [Themeable(false)]
    [Category("Behavior")]
    [Description("Establece si el control va a pintar la jornada de verano")]
    [DefaultValue(false)]
    public bool JornadaVerano
    {
        get { return miProperty._jornadaVerano; }
        set { miProperty._jornadaVerano = value; SaveControlState(); }
    }
   
    [Browsable(true)]
    [Themeable(false)]
    [Category("Behavior")]
    [Description("Establece si se pueden seleccionar los días en el calendario.")]
    [DefaultValue(true)]
    public bool DayIsSelectable
    {
        get { return miProperty._dayIsSelectable; }
        set { miProperty._dayIsSelectable = value; SaveControlState(); }
    }

    [Browsable(true)]
    [Themeable(false)]
    [Category("Behavior")]
    [Description("Establece si el control va a pintar los dias de ausencias")]
    [DefaultValue(false)]
    public bool Ausencias
    {
        get { return miProperty._ausencias; }
        set { miProperty._ausencias = value; SaveControlState(); }
    }

    [Browsable(true)]
    [Themeable(false)]
    [Category("Behavior")]
    [Description("Establece si el control va a pintar las vacaciones")]
    [DefaultValue(false)]
    public bool Vacaciones
    {
        get { return miProperty._vacaciones; }
        set { miProperty._vacaciones = value; SaveControlState(); }
    }

    [Browsable(true)]
    [Themeable(false)]
    [Category("Behavior")]
    [Description("Establece si el control va a pintar los dias de compensasión")]
    [DefaultValue(false)]
    public bool Compensasion
    {
        get { return miProperty._compensasion; }
        set { miProperty._compensasion = value; SaveControlState(); }
    }

    [Browsable(true)]
    [Themeable(false)]
    [Category("Behavior")]
    [Description("Establece si el control va a pintar los dias de Asuntos propios")]
    [DefaultValue(false)]
    public bool AsuntosPropios
    {
        get { return miProperty._asuntosPropios; }
        set { miProperty._asuntosPropios = value; SaveControlState(); }
    }

    #endregion

    #region Eventos

    protected override void OnUnload(EventArgs e)
    {
        System.Diagnostics.Debug.Write(cont.ToString());
        base.OnUnload(e);
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        /*if (!IsPostBack || cambioAnyo)
        {
           /* if (JornadaVerano)
                listJorVerano = JorVerano.DiasJornadaVerano(Anyo);
            if (Festivo)
                listFestivos = festivos.ListaFestivos(Anyo);*/
            
            //this.ActualizaCalendarios();
        //}
        /*if (!forzaUpdatePanel)
            CargaDatos();*/
    }

    protected void Calendar_SelectionChanged(object sender, EventArgs e)
    {
        if (ActivarEdicion.Festivos == TipoEdicion)
            festivos.GuardaFestivo(((Calendar)sender).SelectedDate, Anyo, IdEdificio, IdFestivo);
        else if (ActivarEdicion.JornadaVerano == TipoEdicion)
        {
            if(jorVerano.GuardaJornadaVerano(((Calendar)sender).SelectedDate, Anyo)==0)
                ScriptManager.RegisterStartupScript(this.Page, typeof(System.Web.UI.Page), "mensaje", "var mp = mostrarPopup();", true);
        }
        CargaDatos();

        ((Calendar)(sender)).SelectedDates.Clear();
    }

    protected void Calendar_DayRender(object sender, DayRenderEventArgs e)
    {
      // if (!AjaxControlToolkit.ToolkitScriptManager.GetCurrent(Page).IsInAsyncPostBack)
        if (!IsPostBack || (AjaxControlToolkit.ToolkitScriptManager.GetCurrent(Page).IsInAsyncPostBack && IsInPartialRendering(e.Day.Date.Month))
            || forzaUpdatePanel)
       {
            cont++;
            if (JornadaVerano)
            {
                var diaVerano = listJorVerano.Find(v => v.Dia == e.Day.Date);
                if (diaVerano != null)
                {
                    e.Cell.BackColor = System.Drawing.Color.Blue;
                    e.Cell.ForeColor = System.Drawing.Color.White;
                }
            }

            if (Festivo)
            {
                var diaFestivo = listFestivos.Find(f => f.Dia == e.Day.Date);

                if (diaFestivo != null)
                {
                    //Nacional
                    if (diaFestivo.IdTipoFestivo == 1)
                    {
                        e.Cell.BackColor = System.Drawing.Color.Red;
                        e.Cell.ForeColor = System.Drawing.Color.White;
                    }
                    else if (diaFestivo.IdTipoFestivo == 2)
                    {
                        e.Cell.BackColor = System.Drawing.Color.Coral;
                        e.Cell.ForeColor = System.Drawing.Color.White;
                    }
                    else if (diaFestivo.IdTipoFestivo == 3)
                    {
                        e.Cell.BackColor = System.Drawing.Color.Yellow;
                    }
                }
            }

            if (Vacaciones) 
            {
                var diaVacaciones = listVacaciones.Find(f => f.Fecha == e.Day.Date);
                if (diaVacaciones != null)
                {

                    switch (diaVacaciones.idTipoFalta)
                    {
                        case 2:
                            e.Cell.BackColor = System.Drawing.Color.Lime;
                            break;

                        case 3:
                            e.Cell.BackColor = System.Drawing.Color.Maroon;
                            
                            break;

                        case 4:
                            e.Cell.BackColor = System.Drawing.Color.Gray;
                            break;
                    }
                    e.Cell.ForeColor = System.Drawing.Color.White;

                    switch (diaVacaciones.IdEstadoVacaciones)
                    { 
                        case 2:
                            e.Cell.Controls.Add(imgQuestion);
                            break;

                        case 3:
                            e.Cell.Controls.Add(imgOk);
                            break;

                        case 4:
                            e.Cell.Controls.Add(imgNotOk);
                            break;
                    }

                }

            }
            if (AsuntosPropios) { }
            if (Compensasion) { }
            

            if ((e.Day.IsWeekend == true) && (IdFestivo == null) && (IdEdificio == null))
            {
                e.Day.IsSelectable = false;
            }

            if (e.Day.IsOtherMonth == true)
            {
                e.Cell.ForeColor = System.Drawing.Color.White;
                e.Cell.BackColor = System.Drawing.Color.White;
                e.Day.IsSelectable = false;
            }

            e.Day.IsSelectable = DayIsSelectable;
        }
    }


    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        Page.RegisterRequiresControlState(this);
    }

    protected override object SaveControlState()
    {
        return this.miProperty;
    }

    protected override void LoadControlState(object state)
    {
        if (state != null)
        {
            miProperty = new Propiedades();
            miProperty = (Propiedades)state;         
        }

    }

    #endregion

    #region Métodos privados.

    protected void ActualizaCalendarios()
    {

        using (var calendario = new Calendario(miProperty.anyo))
        {
            Calendar1.VisibleDate = calendario.GetFechaMes(eMeses.Enero);
            Calendar2.VisibleDate = calendario.GetFechaMes(eMeses.Febrero);
            Calendar3.VisibleDate = calendario.GetFechaMes(eMeses.Marzo);
            Calendar4.VisibleDate = calendario.GetFechaMes(eMeses.Abril);
            Calendar5.VisibleDate = calendario.GetFechaMes(eMeses.Mayo);
            Calendar6.VisibleDate = calendario.GetFechaMes(eMeses.Junio);
            Calendar7.VisibleDate = calendario.GetFechaMes(eMeses.Julio);
            Calendar8.VisibleDate = calendario.GetFechaMes(eMeses.Agosto);
            Calendar9.VisibleDate = calendario.GetFechaMes(eMeses.Septiembre);
            Calendar10.VisibleDate = calendario.GetFechaMes(eMeses.Octubre);
            Calendar11.VisibleDate = calendario.GetFechaMes(eMeses.Noviembre);
            Calendar12.VisibleDate = calendario.GetFechaMes(eMeses.Diciembre);
        }
    }

    private bool IsInPartialRendering() 
    {
        return IsInPartialRendering(0);
    }

    private bool IsInPartialRendering(int month)
    {
        if (this.UpdatePanelAbril.IsInPartialRendering || this.UpdatePanelAgosto.IsInPartialRendering || this.UpdatePanelDiciembre.IsInPartialRendering
            || this.UpdatePanelEnero.IsInPartialRendering || this.UpdatePanelFebrero.IsInPartialRendering || this.UpdatePanelJulio.IsInPartialRendering
            || this.UpdatePanelJunio.IsInPartialRendering || this.UpdatePanelMarzo.IsInPartialRendering || this.UpdatePanelMayo.IsInPartialRendering
            || this.UpdatePanelNoviembre.IsInPartialRendering || this.UpdatePanelOctubre.IsInPartialRendering || this.UpdatePanelSeptiembre.IsInPartialRendering)
        {

            if (month == 0)
                return AjaxControlToolkit.ToolkitScriptManager.GetCurrent(Page).AsyncPostBackSourceElementID.Contains("Calendar" + month);
            else
                return true;

        }
        return false;
    }

    private bool IsInPartialRenderingPanel(int month)
    {
        return AjaxControlToolkit.ToolkitScriptManager.GetCurrent(Page).AsyncPostBackSourceElementID.Contains("Calendar" + month);
    }

    private bool IsInPartialRenderingMonth()
    {
        return ScriptManager.GetCurrent(Page).AsyncPostBackSourceElementID.Contains(ScriptManager.GetCurrent(Page).AsyncPostBackSourceElementID);
    }

    private void CargaDatos()
    {
        if (Festivo)
            if (IdEdificio == null)
                listFestivos = festivos.ListaFestivos(Anyo);
            else
                listFestivos = festivos.ListaFestivos(Anyo, IdEdificio);
        if (JornadaVerano)
            listJorVerano = jorVerano.DiasJornadaVerano(Anyo);
        if (Vacaciones)
        {
            listVacaciones = oVacaciones.GetVacacionesUsuario(MiSession.UserName, DateTime.Now.Year);
            imgOk = new Image { ImageUrl = "../img/ok.png" };
            imgNotOk = new Image { ImageUrl = "../img/not_ok.png" };
            imgQuestion = new Image { ImageUrl = "../img/question.png" };

        }
    }

    #endregion

    #region Método públicos.
    /// <summary>
    /// Cambia el año activo
    /// </summary>
    /// <param name="anyo"></param>
    public void AsignarAnyo(int anyo)
    {
        Anyo = anyo;
        cambioAnyo = true;
        this.ActualizaCalendarios();
    }
    /// <summary>
    /// Actualiza el control calendario para el calendario Laboral.
    /// </summary>
    /// <param name="idEdificio">Edificio a mostrar el calendario Laboral</param>
    /// <param name="idFestivo">Tipo de festivo a mostrar en el calendario Laboral</param>
    public void UpdatePaneles(int? idEdificio, int idFestivo)
    {
        if (!IsInPartialRendering())
        {
            this.UpdatePanelAbril.Update();
            this.UpdatePanelAgosto.Update();
            this.UpdatePanelDiciembre.Update();
            this.UpdatePanelEnero.Update();
            this.UpdatePanelFebrero.Update();
            this.UpdatePanelJulio.Update();
            this.UpdatePanelJunio.Update();
            this.UpdatePanelMarzo.Update();
            this.UpdatePanelMayo.Update();
            this.UpdatePanelNoviembre.Update();
            this.UpdatePanelOctubre.Update();
            this.UpdatePanelSeptiembre.Update();
            forzaUpdatePanel = true;
        }

        this.IdEdificio = idEdificio;
        this.IdFestivo = idFestivo;

        CargaDatos();
    }
    /// <summary>
    /// Actualiza el control calendario para el calendario Laboral.
    /// </summary>
    /// <param name="idFestivo">Edificio a mostrar el calendario Laboral</param>
    public void UpdatePaneles(int idFestivo) 
    {
        UpdatePaneles(null, idFestivo);
    }

    /// <summary>
    /// Actualiza el control calendario para un usuario.
    /// </summary>
    /// <param name="idUsuario"></param>
    public void UpdatePanelesByUser(string idUsuario)
    {
        if (!IsInPartialRendering())
        {
            this.UpdatePanelAbril.Update();
            this.UpdatePanelAgosto.Update();
            this.UpdatePanelDiciembre.Update();
            this.UpdatePanelEnero.Update();
            this.UpdatePanelFebrero.Update();
            this.UpdatePanelJulio.Update();
            this.UpdatePanelJunio.Update();
            this.UpdatePanelMarzo.Update();
            this.UpdatePanelMayo.Update();
            this.UpdatePanelNoviembre.Update();
            this.UpdatePanelOctubre.Update();
            this.UpdatePanelSeptiembre.Update();
            forzaUpdatePanel = true;
        }

        this.IdEdificio = MiSession.IdEdificio;
        this.IdFestivo = 2;
        CargaDatos();
    }

    public void CambiarEstadoEdicion(ActivarEdicion Tipo )
    {
        TipoEdicion = Tipo;
    }

    #endregion
}